
package com.trydofor.id.mina;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.trydofor.id.byta.Bytable;
import com.trydofor.id.byta.Bytes;
import com.trydofor.id.byta.Head;
import com.trydofor.id.byta.Packet;

/**
 * thread safe packet encoder
 * 
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class PacketEncoder extends ProtocolEncoderAdapter {
    
    /**
     * constructor
     */
    public PacketEncoder() {
    }
    
    /**
     * {@inheritDoc}
     */
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
        
        Packet packet = (Packet) message; // throw
        
        Bytable<?> body = packet.getBody();
        byte[] bytes = body.toBytes();
        int bodySize = bytes.length;
        
        Head head = packet.getHead();
        head.setBodyType(Bytes.classType(body.getClass()));
        head.setBodySize(bodySize);
        
        IoBuffer buffer = IoBuffer.allocate(Head.BYTE_SIZE + bodySize, false);
        // head
        buffer.putLong(Head.FIXED_TOKEN);
        buffer.putLong(head.getDealCode());
        buffer.putInt(head.getAuthCode());
        buffer.putInt(head.getBodyType());
        buffer.putInt(head.getBodySize());
        // body
        buffer.put(bytes);
        //
        buffer.flip();
        out.write(buffer);
    }
}
